﻿namespace PmSoft.Cache.Abstractions;

/// <summary>
/// 缓存服务接口，仅用于实体缓存管理
/// </summary>
public interface ICacheService
{
	/// <summary>
	/// 是否启用分布式缓存
	/// </summary>
	bool EnableDistributedCache { get; }

	/// <summary>
	/// 从缓存获取实体（同步）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <returns>缓存的实体，若不存在则返回 null</returns>
	T? Get<T>(string cacheKey);

	/// <summary>
	/// 从缓存获取实体（异步）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <returns>缓存的实体，若不存在则返回 null</returns>
	Task<T?> GetAsync<T>(string cacheKey);

	/// <summary>
	/// 尝试从缓存获取实体
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <param name="value">输出缓存值</param>
	/// <returns>是否成功获取</returns>
	bool TryGetValue<T>(string cacheKey, out T? value);

	/// <summary>
	/// 从一级缓存获取实体（同步），分布式模式下直接访问分布式缓存
	/// </summary>
	/// <typeparam name="T">实体类型，必须为引用类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <returns>缓存的实体，若不存在则返回 null</returns>
	T? GetFromFirstLevel<T>(string cacheKey) where T : class;

	/// <summary>
	/// 从一级缓存获取实体（异步），分布式模式下直接访问分布式缓存
	/// </summary>
	/// <typeparam name="T">实体类型，必须为引用类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <returns>缓存的实体，若不存在则返回 null</returns>
	Task<T?> GetFromFirstLevelAsync<T>(string cacheKey) where T : class;

	/// <summary>
	/// 移除实体缓存（同步）
	/// </summary>
	/// <param name="cacheKey">缓存键</param>
	void Remove(string cacheKey);

	/// <summary>
	/// 移除实体缓存（异步）
	/// </summary>
	/// <param name="cacheKey">缓存键</param>
	Task RemoveAsync(string cacheKey);

	/// <summary>
	/// 设置实体缓存（同步，指定时间）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <param name="value">实体值</param>
	/// <param name="timeSpan">过期时间</param>
	void Set<T>(string cacheKey, T value, TimeSpan timeSpan);

	/// <summary>
	/// 设置实体缓存（同步，指定过期类型）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <param name="value">实体值</param>
	/// <param name="cachingExpirationType">缓存过期类型</param>
	void Set<T>(string cacheKey, T value, CachingExpirationType cachingExpirationType);

	/// <summary>
	/// 设置实体缓存（异步，指定时间）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <param name="value">实体值</param>
	/// <param name="timeSpan">过期时间</param>
	Task SetAsync<T>(string cacheKey, T value, TimeSpan timeSpan);

	/// <summary>
	/// 设置实体缓存（异步，指定过期类型）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="cacheKey">缓存键</param>
	/// <param name="value">实体值</param>
	/// <param name="cachingExpirationType">缓存过期类型</param>
	Task SetAsync<T>(string cacheKey, T value, CachingExpirationType cachingExpirationType);
}